\documentclass[10pt, a4paper, titlepage]{article}
\usepackage[utf8]{inputenc}
\usepackage[francais]{babel}
\usepackage[T1]{fontenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{graphicx}
\usepackage{listings}
\usepackage{url}
\usepackage[nottoc, notlof, notlot]{tocbibind}

\newcommand{\HRule}{\rule{\linewidth}{0.5mm}}

\usepackage{color}
\definecolor{dkgreen}{rgb}{0,0.6,0}
\definecolor{gray}{rgb}{0.5,0.5,0.5}
\definecolor{mauve}{rgb}{0.90,0,0.52}

\renewcommand\lstlistingname{Algorithme}
\renewcommand\lstlistlistingname{Liste des algorithmes}
\lstset{ %
  language=C++,                % the language of the code
  basicstyle=\footnotesize,           % the size of the fonts that are used for the code
  numbers=left,                   % where to put the line-numbers
  numberstyle=\tiny\color{gray},  % the style that is used for the line-numbers
  stepnumber=1,                   % the step between two line-numbers. If it's 1, each line
                                  % will be numbered
  numbersep=5pt,                  % how far the line-numbers are from the code
  backgroundcolor=\color{white},      % choose the background color. You must add \usepackage{color}
  showspaces=false,               % show spaces adding particular underscores
  showstringspaces=false,         % underline spaces within strings
  showtabs=false,                 % show tabs within strings adding particular underscores
  frame=single,                   % adds a frame around the code
  rulecolor=\color{black},        % if not set, the frame-color may be changed on line-breaks within not-black text (e.g. commens (green here))
  tabsize=2,                      % sets default tabsize to 2 spaces
  captionpos=b,                   % sets the caption-position to bottom
  breaklines=true,                % sets automatic line breaking
  breakatwhitespace=false,        % sets if automatic breaks should only happen at whitespace
  title=\lstname,                   % show the filename of files included with \lstinputlisting;
                                  % also try caption instead of title
  keywordstyle=\color{blue}\bfseries,          % keyword style
  commentstyle=\color{dkgreen},       % comment style
  stringstyle=\color{mauve},         % string literal style
  escapeinside={\%*}{*)},            % if you want to add a comment within your code
  morekeywords={*,...}               % if you want to add more keywords to the set
}



\begin{document}
%\maketitle
\input{titlepage.tex}

\pagebreak
\thispagestyle{empty}
\setcounter{page}{0}
\null
\pagebreak

\tableofcontents

\pagebreak
\thispagestyle{empty}
\setcounter{page}{1}
\null
\pagebreak

\clearpage
\section*{Introduction}
\addcontentsline{toc}{section}{Introduction}
%Univ fcomte blabla

	Actuellement en dernière année de Master informatique à l'Université de Sciences et Techniques de Franche-Comté, nous avons eu l'opportunité de faire un projet semestriel pour clôturer nos études universitaires. Ce projet s'est déroulé sur une durée de quatre mois et nous avons choisi d'en déterminer nous même le sujet.

	La création de jeux vidéo est l'un des domaines les plus riches de la programmation informatique. On y trouve des tâches très variées allant du moteur physique à l'intelligence artificielle ou encore au réseau. C'est un domaine très vaste et très intéressant obligeant les développeurs à des réflexions poussées pour la mise en \oe uvre des algorithmes de jeux.
    Tous deux friands de jeux vidéo et dans l'optique d'un stage dans l'univers du développement de logiciels ludiques, nous avons rapidement orienté nos recherches dans ce domaine pour proposer un projet que nous aurions à développer de A à Z.

    %NB : Pas à mettre dans l'intro
    %De plus, le jeu vidéo se prête très bien aux questions relatives au réseau, à l'optimisation des communication et surtout à la synchronisation des ressources pour éviter des incohérence entre les différents affichages des joueurs.

%Le développement du jeu à proprement parler ne devait pas représenter la majorité du temps de travail, et cette observation à guidée nos choix quant au jeu que nous voulions faire naitre.


    \medskip
    Le projet de deuxième année de Master doit mettre en avant les connaissances acquises lors de notre cursus dans la spécialité Systèmes Distribués et Réseaux. Nous avons cherché un projet qui pouvait nous permettre d'appliquer ce que nous avons appris. Cette spécialité nous a sensibilisés aux problèmes de synchronisation et communication dans des systèmes distribués. Nous avons donc opté pour un jeu simple en réseau centré sur les communications et la distribution du travail.
    
    %sensibilisés ==> COD placé avant le verbe ;)

%Nous dévoilerons en premier temps le projet plus en détails, nous donnerons ensuite les informations sur les technologies que nous avons utilisés pour notre développement. Nous terminerons par une description détaillée des mécanismes que nous avons mis en place, nous expliquerons aussi quels décisions nous avons du prendre, pourquoi nous les avons prises et comment nous les avons mises en place.
%appronfondir le pourquoi du choix du sujet

\medskip
%Donner le plan du doc
Dans ce rapport, nous commençons par décrire plus en détails le sujet de notre projet, qu'elles étaient nos priorités, puis nous abordons les différentes technologies que nous avons utilisées pour le mettre en place.
Ensuite, nous présentons l'architecture du jeu, les outils de communication et de synchronisation qui entrent en \oe uvre, et nous montrons quelques captures d'écran du rendu final de notre travail.
Finalement, nous concluons par un bilan technique et personnel sur l'ensemble du projet.


\clearpage
\section{Présentation du projet}
	Pour ce projet, notre objectif est de réaliser un jeu en réseau. Les points clefs de ce jeu étant qu'il doit être possible de jouer avec au moins deux joueurs dans un même environnement. Ces joueurs peuvent interagir les uns avec les autres de même qu'avec l'environnement. Il y a donc un important système de communications en temps réel à mettre en place pour satisfaire ces objectifs.

\medskip
Lors de la deuxième année de Master, nous avons choisi notre spécialité et nous nous sommes orientés en Systèmes Distribués et Réseaux (SDR). Nous avons acquis grâce à cette spécialité de solides bases en ce qui concerne les réseaux distribués ainsi que les obligations de synchronisation. %Cela nous permet d'avoir des bases de réflexions pour alléger les communications et des algorithmes de résistance aux pannes.

%D'abord points importants : comm, repartitions calculs
	Nous avons décidé de donner la priorité dans notre projet au développement des fonctionnalités de communications, de synchronisation et d'optimisation de code pour alléger les charges sur les machines et sur le réseau, inscrivant ainsi notre projet dans la thématique de notre spécialité. 
	Nous avons réfléchi aux moyens de mettre en place un système en temps réel pour les communications en ayant le moins de latence possible tant au niveau de l'affichage que des calculs du moteur de jeu. 
La rapidité et la fluidité sont des points importants dans un jeu, mais la synchronisation a une part importante dans la cohérence des données affichées sur les différents clients.

\medskip
Pour pouvoir se concentrer sur les points précédents, nous avons décidé de faire des choses simples en terme de graphismes afin de ne pas passer le principal de notre temps sur ce sujet. Notre première décision fut de faire un jeu en deux dimensions (2D) pour simplifier au maximum la gestion de l'affichage et pouvoir prendre plus de temps sur le développement du moteur de jeu. Et la deuxième décision prise fut celle de faire un jeu de plateforme, car c'est le style de jeu le plus adapté à la 2D. Grâce à ce choix de simplicité pour les graphismes et le système de jeu, nous pouvons centrer notre projet sur les communications réseau  et les questions de synchronisation et d'optimisation.

\clearpage
\section{Technologies}
Pour développer notre jeu, nous avons eu recours à plusieurs technologies complémentaires, ce qui nous a évité de tout développer nous même. Il nous a fallu utiliser un moteur graphique pour gérer les affichages de nos objets dans une fenêtre, un moteur physique pour la gestion de la gravité et des collisions mais aussi un créateur de carte.
Dans cette partie, nous abordons les outils que nous avons utilisés pour le développement à proprement parlé (IDE, langage de programmation, serveur de versionnage), puis nous donnons des informations sur les API utilisées pour la création du jeu vidéo.

    \subsection{Environnement de développement}
%Répartition des tâches, svn, c++, visual
        \subsubsection*{Langage, IDE et Subversion}
Nous avons choisi de développer en utilisant le langage C++ qui offre de très nombreuses bibliothèques et que nous avons très peu eu l'occasion de pratiquer dans notre cursus universitaire. Le stage que nous allons réaliser à la fin de cette année nous amènera également à développer dans ce langage. Cela nous faisait donc une bonne opportunité d'approfondir notre connaissance de ce langage à l'aide d'un projet utilisant plusieurs facettes de l'informatique. Ensuite, pour la spécialité \textit{SDR} nous avions déjà réalisé un projet de synchronisation et communication dans le langage Java et il nous a sembler bon de nous exercer dans un autre langage.

    Pour l'environnement de développement intégré, nous avons opté pour Microsoft Visual Studio 2012. Il est très complet pour le langage C++ et là aussi cela nous permettait de nous habituer à un IDE que nous avons peu utilisé et qui est très souvent mis en place dans les entreprises de développement. C'est en effet l'outil utilisé dans l'entreprise qui nous accueillera durant notre stage. Ainsi, nous avons pu durant ce projet nous exercer à l'utilisation de ce logiciel.

    Nous avons utilisé le gestionnaire de versions Apache Subversion \cite{svn} afin de centraliser notre travail. Son utilisation a été approuvée et éprouvée au fil du temps et c'est aujourd'hui une technologie puissante et stable qui offre des possibilité de gestion de versions très poussées et puissantes.

    \subsection{Le choix de l'Open Source}
Mis à part Visual Studio dont nous avons eu une licence par le biais du programme pour étudiants DreamSpark de Microsoft, tous les outils, bibliothèques et ressources utilisés durant notre projet étaient issus du monde de l'Open Source. Nous avons fait ce choix car nous pensons que les outils de l'univers du logiciel libre sont tout aussi puissant et complet que les logiciels propriétaire.
%Nous avons fait ce choix car nous n'avions pas de budget pour acheter des outils spécifiques. 
Ce choix nous a aussi permis d'adapter certains outils à notre projet en modifiant et en compilant les sources modifiées.
%TODO Ca serait plus classe de dire que c'est par principe que parce qu'on a pas de thunes ! :P ==> Check

    \subsection{Tiled et TmxParser}
    %Comment on a mis en place TMXParser
    Pour dessiner le niveau dans lequel nos joueurs évoluent, nous avons utilisé le logiciel \texttt{Tiled} \cite{Tiled}. Celui-ci permet de construire des images en assemblant différentes petites tuiles, qui font dans notre cas 16 pixels par 16 pixels, afin de dessiner les différentes plateformes qui vont composer le niveau. La figure \ref{ExempleTiled} montre un exemple de ce que l'on peut créer avec ce logiciel et les tuiles présentées en figure \ref{ExempleTuile}. Nous avons récupéré des tuiles open source sur le site \texttt{Open Game Art}\cite{OpenGameArt}, qui propose de nombreux contenus de manière libre, afin de ne pas perdre de temps à faire les graphismes nous même. Toutes les informations sur le niveau et les objets qu'il contient sont alors sauvegardés dans un fichier standardisé avec l'extension \texttt{tmx}.
%TODO Note LP : Mettre des exemples de graphismes ==> check

	\begin{figure}[h]
        \centering
        \includegraphics[scale=0.4]{img/area02_mock.jpg}
        \caption{Exemple de réalisation faite avec Tiled}
        \label{ExempleTiled}
    \end{figure}
    
    \begin{figure}[h]
        \centering
        \includegraphics[scale=0.4]{img/area02_level_tiles.png}
        \caption{Tuiles associées à la figure \ref{ExempleTiled}}
        \label{ExempleTuile}
    \end{figure}

    \medskip
    Le format \texttt{tmx} est un dialecte \texttt{XML}. Il suffit ensuite de parser ces données pour en extraire toutes les informations nécessaires à la création des objets dans notre code. Pour cela, nous avons utilisé une bibliothèque appelée \texttt{Tmx Parser} \cite{TmxParser} développée par Engine Games. Cette bibliothèque est basée sur \texttt{zlib} \cite{zlib} pour la compression et la décompression des fichiers ainsi que sur \texttt{TinyXML} \cite{tinyxml} et DOM pour la lecture du fichier XML. Quelques corrections seulement ont été nécessaires pour mettre à jour la bibliothèque afin de l'utiliser dans notre projet. Son utilisation a donc été un grand gain de temps pour nous en nous évitant de développer nous même tout un parser.

    Ainsi, au démarrage du serveur du jeu, nous parsons le fichier \texttt{tmx} sauvegardant le niveau en cours et nous pouvons récupérer chacun des objets y figurant son type, sa taille ainsi que sa position, pour le créer en tant qu'objet C++. 
    L'algorithme \ref{CodeTmx} dans la section \ref{code} présente cette lecture du fichier \texttt{tmx} pour la création des objets \texttt{Box2D} faisant partie du niveau.

    \subsection{Simulation physique avec \texttt{Box2D}}
    Il nous semblait important de respecter quelques règles de bases de tout jeu vidéo, comme par exemple le fait que le joueur ne doit pas passer à travers les murs ou le sol. Il faut également que le personnage respecte une certaine physique dans ses mouvements, notamment lorsqu'il chute.

    Nous avons donc réfléchi aux différentes possibilités que nous avions pour mettre en place tout cela. La première solution est d'implémenter nous même des moyens de vérifier les collisions entre objets ainsi que des règles de physique. La seconde solution est de regarder l'existant pour voir si quelque chose qui correspond à notre projet et ce que nous souhaitons faire existe déjà. Nous avons ainsi trouvé le moteur physique \texttt{Box2D} \cite{b2d}. \texttt{Box2D} est une librairie open source en \texttt{C++} pour simuler le comportement d'entités en 2D. Elle permet de gérer les détections de collisions entre les objets créés ainsi que de leur appliquer des forces physiques avec des notions de gravité et de friction afin de représenter au mieux la réalité. C'est une librairie qui correspond tout à fait à nos besoins, nous avons donc choisi de l'utiliser au sein de notre projet.

    \subsubsection*{Création du monde}
    \texttt{Box2D} fonctionne de manière assez simple. Il faut tout d'abord définir un monde et la physique qui le gouverne, en spécifiant une gravité. Notons également que \texttt{Box2D} possède sa propre échelle. Une unité ne correspond pas à un pixel, il faut choisir son propre coefficient pour créer son univers. Nous avons choisi un coefficient multiplicateur faisant que nos personnages joueurs font environ 1 mètre 80 en représentation \texttt{Box2D}. Les autres éléments du jeu sont représentés proportionnellement.

    Tous les objets qui composent notre niveau sont représentés par des objets de type \texttt{Body} dont les propriétés varient. Les premiers objets qui font parti du niveau sont les plateformes sur lesquels les joueurs évoluent. Celles-ci sont créées en tant qu'objets \texttt{Box2D} lors de la lecture du fichier \texttt{tmx}. Ces \textit{corps} sont définis comme des objets denses, au travers desquels on ne peut pas passer, et fixes dans le décor. Ils ne seront jamais modifiés au cours de la partie.

    Viennent ensuite les joueurs. Eux sont également denses mais, contrairement aux plateformes, ils sont mobiles. Nous les définissons donc comme des objets dynamiques, de type \texttt{b2\_dynamicBody}. Ils ne peuvent ainsi pas passer les uns au travers des autres. Ils sont également sujet à la gravité définie dans notre monde, car ils peuvent sauter ou tomber dans un trou par exemple.

    Les monstres, comme les joueurs, sont denses et mobiles. Cependant ils suivent un mouvement défini et ne peuvent pas sauter. Ils ne sont donc pas défini de la même manière que les joueurs, mais comme des objets cinématiques, de type \texttt{b2\_kinematicBody}. Ils ne sont pas sujets à la gravité.

    Le dernier type d'objet que l'on rencontre dans notre jeu est les objets que l'on peut capturer, telles les gemmes. Ces objets sont immobiles et non sujets à la gravité, ils sont de type statique, \texttt{b2\_staticBody}. 
    
    Finalement, dans chaque niveau de jeu, il y a une porte de sortie. Cette porte est statique également. 
    
    Les joueurs, les objets que l'on peut capturer et les portes sont des senseurs (\texttt{sensor}). C'est-à-dire qu'il est possible de détecter lorsqu'ils sont en contact avec d'autres éléments de l'environnement.


    \subsubsection*{L'écoute du monde}
    Maintenant que notre monde est défini, il faut savoir tout ce qui se passe dans celui-ci. Est-ce qu'un joueur est mort en rencontrant un monstre ? A-t-il capturé une gemme ? A-t-il trouvé la sortie du niveau ?

    Pour être au courant de tout cela, nous avons mis en place un \texttt{WorldListener}. Celui-ci écoute en permanence ce qui se passe au sein de notre monde. Tous les objets, monstres et joueurs implémentent une même interface, \texttt{ContactObject}, qui nous permet de savoir quand ils entrent en contact les uns avec les autres. Ensuite, selon les types des objets qui se rencontrent, notre monde se met à jour. Par exemple, si un joueur entre en contact avec une gemme, le score du joueur va être augmenté et la gemme va disparaître du niveau afin de ne pas pouvoir être à nouveau capturée. Si un joueur rencontre un monstre, le joueur va mourir et ne sera plus jouable pour ce niveau. Et finalement, si un joueur entre en contact avec la porte de sortie du niveau, le niveau est terminé pour les deux joueurs.
    
    L'algorithme \ref{CodeWorldListener} dans la partie \ref{code} décrit la fonction qui est appelée à chaque contact entre deux objets étant écoutés par notre \texttt{WorldListener}.


    \subsection{L'affichage avec SFML}
    %Comment on a mis en place SFML
    Pour toute la partie affichage du jeu du côté notre client, nous nous sommes appuyé sur la bibliothèque SFML : \textit{Simple and Fast Multimedia Library} \cite{sfml}. C'est une bibliothèque très complète qui permet de faire des graphismes 2D en se basant sur \texttt{OpenGL}.

    Mais cette bibliothèque ne se limite pas seulement aux graphismes. Elle est en effet composée de cinq modules :
    \begin{itemize}
        \item Le module \texttt{Graphics} : c'est lui qui nous permet d'afficher toutes nos images chez le client. Il permet également de générer et afficher des formes simples.
        \item Le module \texttt{Window} : il permet de créer les fenêtres et gère les interactions avec l'utilisateur.
        \item Le module \texttt{Network} : il permet de créer des \textit{sockets}, en connexion TCP ou UDP, pour les communications.
        \item Le module \texttt{System} : ce module permet de créer et gérer des \textit{threads}
        \item Le module \texttt{Audio} : ce dernier module permet de jouer un son ou une musique facilement.
    \end{itemize}

    Parmi ces modules, nous avons utilisé les quatre premiers. Mais nous nous concentrons ici uniquement sur les deux modules en lien avec l'interface graphique et nous abordons notre utilisation des modules \texttt{System} et \texttt{Network} dans la section \ref{comm}.


        \subsubsection*{Ouvrir et gérer une fenêtre SFML}
    Pour l'ouverture et la gestion de la fenêtre de jeu chez les clients, nous utilisons donc le module \texttt{Window} de SFML. Une fenêtre peut être créée et ouverte directement dès sa construction grâce à la bibliothèque, avec en paramètre lors de sa création sa taille et son titre. Une fois notre fenêtre créée, une boucle infinie nous permet de récupérer en permanence toutes les interactions de l'utilisateur et de mettre à jour la fenêtre, c'est la boucle principale de notre programme.

    Nous utilisons donc une boucle \texttt{while} afin d'inspecter tous les événements se déroulant, ceci nous permet de ne pas rater d'événement au cas où il y en aurait plusieurs en attente d'être traités. En effet, SFML nous offre une fonction simple, \texttt{pollEvent}, qui renvoie un booléen pour nous indiquer si un événement est en attente ou non. Les événements sont ensuite analysés afin d'envoyer leur nature au serveur.

    \medskip
    Il y a en effet plusieurs types d'événements dans SFML. Le premier événements incontournable dont nous surveillons le déclenchement est l'événement \texttt{Closed}. Cet événement est une demande de fermeture de la fenêtre d'affichage. En réaction, nous appelons une méthode, \texttt{window.close()}, qui se charge effectivement de fermer la fenêtre.

    Les deux événements les plus importants dans notre cas sont les événements \texttt{KeyPressed} et \texttt{KeyReleased}, qui sont déclenchés lorsqu'une touche du clavier est respectivement pressée ou relâchée. Ce sont ces événements qui vont caractériser les actions faites par nos joueurs, ils sont donc à la base de nos échanges entre le client et le serveur. 
    
    Tous ces évènement sont stockées dans une liste qui fait office de file d'attente et permet de gérer les appuis multiples sur le clavier. C'est cette liste que nous utilisons pour connaitre les actions réalisées par les joueurs.
    
    %TODO finir un peu mieux  ==> check? :P


    \subsubsection*{Sprites et textures}
    SFML utilise pour l'affichage graphique deux objets différents : les textures et les sprites. Les textures sont en fait des images qui sont pré-chargées dans la mémoire graphique avant d'être utilisées. Ce qui est ensuite réellement affiché sont les sprites. Ces sprites sont en fait des rectangles de vue placés sur une texture. C'est ce qui est contenu dans ces sprites qui sera ensuite affiché dans la fenêtre, comme illustré dans la figure \ref{ExplicationSpriteTexture}.

    \begin{figure}[h]
        \centering
        \includegraphics[scale=0.4]{img/ExplicationSpriteTexture.png}
        \caption{Fonctionnement des textures et des sprites}
        \label{ExplicationSpriteTexture}
    \end{figure}

	\medskip
    Nous utilisons le couple sprites et textures pour chaque objet du jeu qui est animé. Les décors fixes étant générés avec \texttt{TmxParser}, nous n'avons pas besoin de gérer les sprites pour ces derniers. Chaque objet peut posséder plusieurs textures. Un personnage par exemple possède une texture de déplacement vers la gauche, une pour le déplacement vers la droite, pour le saut, etc...

    Dans une texture, on retrouve plusieurs images d'un même objet dans différentes positions représentant un enchaînement dans une animation. Pour que l'animation fonctionne correctement, nous avons mis en place un système simple qui est celui ci :
    \begin{itemize}
        \item Lors de l'initialisation de l'objet dans le client, sa texture est chargée dans une variable de type \texttt{sf::Texture}.
        \item Toujours lors de l'initialisation de l'objet, nous remplissons une matrice qui contient la position du sprite pour chaque séquence de l'animation. Chaque position est en fait un \texttt{sf::Vector2f} qui contient le couple de valeurs $x$ et $y$ représentant la position. Les sprites ayant, pour un même objet, toujours la même taille, cette information est stockée dans un unique \texttt{sf::Vector2f} pour toutes les textures de l'objet. La figure \ref{placementSpriteAnimation} illustre ceci.
        \item Ensuite, à chaque itération de boucle de partie dans le thread d'affichage du client, la méthode \texttt{animation} de l'objet est appelée. Cette méthode commence par charger la bonne texture en fonction de ce que l'objet fait (déplacement, saut, chute, etc...) puis à l'aide d'un chronomètre de type \texttt{sf::clock} la méthode déplace le sprite dans la texture en fonction de l'avancement de la séquence d'animation.
    \end{itemize}
    
    La fonction \ref{CodeAnimation} dans la partie \ref{code} présente l'affichage d'un joueur selon son action actuel et la séquence d'animation dans laquelle il se trouve actuellement.

    \begin{figure}[h]
        \centering
        \includegraphics[scale=0.4]{img/placementSpriteAnimation.png}
        \caption{Exemple d'initialisation d'une matrice de positionnement de sprites}
        \label{placementSpriteAnimation}
    \end{figure}


    \subsubsection*{Conversion entre Box2D et SFML}
    \texttt{Box2D} et \texttt{SFML} sont donc les deux bibliothèques qui nous servent à représenter nos objets, l'une du côté du serveur, l'autre du côté du client. Elles n'ont cependant pas du tout la même manière de les représenter.

    Comme nous l'avons dit, \texttt{Box2D} possède sa propre mise à l'échelle des objets. SFML quand à lui représente les tailles des objets en pixels, comme nous avons le plus l'habitude de le voir. De même, les deux bibliothèques n'ont pas le même repère, elles ont l'axe des $y$ inversé l'une par rapport à l'autre. Et pour finir, le point de départ de la représentation de l'image n'est pas le même. \texttt{Box2D} représente un objet en partant du centre de celui-ci alors que \texttt{SFML} place son origine en haut à gauche de l'image. \texttt{Box2D} prend donc en compte des demi-hauteurs et des demi-largeurs. Ces différences sont représentées sur la figure \ref{SFML_B2D_repere}.


    Il nous a donc fallu faire très attention à bien faire les conversions en ce qui concerne les positions et les tailles des différents objets lorsque nous communiquons entre le serveur et le client. L'algorithme \ref{CodeConversion} dans la section \ref{code} présente les fonctions de conversion d'une position de SFML à Box2D et réciproquement. 


\begin{figure}[hb]
        \centering
        \includegraphics[scale=0.5]{img/repere.jpeg}
        \caption{Présentation des repères de Box2D et SFML}
        \label{SFML_B2D_repere}
    \end{figure}

    \clearpage
    \section{Réalisation}
    

    Dans cette partie, nous abordons comment nous avons organisé notre espace de travail (dossier, librairies, etc). En ce qui concerne l'architecture de notre projet, nous remarquons que l'organisation se rapproche énormément de l'architecture Client/Serveur du jeu. Nous présentons finalement comment nous faisons communiquer chacune des parties du projet et ce que nous avons mis en place pour éviter des problèmes de synchronisation.

    \subsection{Architecture}
    Notre code est divisé en trois parties distinctes. Ces trois parties se rapprochent énormément de l'architecture Client/Serveur du jeu :

    \begin{itemize}
        \item La première partie est la partie qui contient les codes concernant le client de jeu. Fichiers sources des objets apparaissant dans le client, code de gestion de l'affichage, etc...
        \item La deuxième partie est celle gérant le fonctionnement coté serveur. Code des objets \textit{physiques}, gestion de la physique avec \texttt{Box2D}, etc...
        \item La dernière partie est un ensemble de fichiers sources transformés en une seule et même librairie. Nous l'avons appelé \texttt{Common}. Cette libraire contient tous nos codes communs aux deux parties précédentes (Énumération des couleurs des objets, des actions ou des directions, ...).
    \end{itemize}


    \subsubsection*{Architecture moteur de jeu et réseau}
    \label{archiJeuReseau}
    \begin{figure}[h]
        \centering
        \includegraphics[scale=0.5]{img/StructureClientServeur.jpeg}
        \caption{Structure de l'application avec deux clients}
        \label{StructClientServ}
    \end{figure}
    %Comment sont découpées les parties du moteur : Client/Serveur, combien de sockets, ...
        \paragraph{Le choix de la séparation Client/Serveur}
    Un jeu vidéo en réseau fonctionnant sur un système entièrement distribué n'est pas pertinent dans notre cas. En effet, si nous avions mis en place un tel système, les informations de chaque joueur auraient été transmises à tous les autres joueurs. Il y aurait eu une surcharge au niveau des sockets de communication. De plus, les calculs du moteur de jeu (pour le déplacement des monstres et les calculs de collisions par exemple) auraient été exécutés par chaque client. Les calculs graphiques des jeux étant déjà très gourmands pour un processeur, le fait de rajouter les calculs moteur sur les clients auraient été une erreur en terme d'optimisation.
    C'est pourquoi nous avons décidé de mettre en place une architecture client/serveur comme représentée par la figure \ref{StructClientServ} dans le cas où nous avons deux clients. 
    
    Voyons à présent quels sont les rôles de chacun.

    \paragraph{Le client, maître de l'affichage}
    
    Le client est divisé en deux threads. Un premier thread gère la réception des informations du serveur et le deuxième gère l'écoute du clavier et se charge de transmettre ces informations au serveur.
        \begin{itemize}
        \item Le client s'occupe de l'affichage et un de ses threads est dédié entièrement à cette partie. C'est lui qui a le rôle d'ouvrir et gérer la fenêtre ainsi que son contenu. Il reçoit les informations concernant la position des objets se trouvant dans le jeu de la part du serveur et se charge de mettre à jour ces objets puis de les afficher avec leurs nouvelles valeurs.
        \item Le deuxième thread est chargé d'écouter les entrées coté client (clavier, souris et manette). Pour notre projet, nous écoutons uniquement le clavier. Le thread en question se met donc en écoute du clavier et lorsqu'une touche est appuyée, il envoie l'information de cette touche au serveur. Dans un but de généricité de notre code, ce n'est pas l'information de la touche qui est transmise mais l'action réalisée. Ainsi, si on désire changer les touches du jeu, nous n'avons besoin de modifier que le client, le serveur recevant de son coté des actions génériques. Chacun des clients peut donc avoir son propre paramétrage des touches lui servant à jouer.
        %TODO appuyer à l'aide d'image
    \end{itemize}
	La figure \ref{FonctionnementClient} présente ce découpage en deux threads.
    
    \begin{figure}[h]
        \centering
        \includegraphics[scale=0.3]{img/fonctionnementClient.jpg}
        \caption{Fonctionnement des deux threads du client}
        \label{FonctionnementClient}
    \end{figure}
     

    \paragraph{Le serveur calcule tout}
    Tout comme le client, le serveur est divisé en plusieurs threads. Un thread principal qui gère les calculs du monde de jeu (physique, déplacements et interactions). Il possède ensuite un nombre de threads égal au nombre de joueurs.
        \begin{itemize}
        \item Les threads non principaux sont chargés de recevoir les informations du client concernant les actions que les joueurs souhaitent réaliser. Une fois qu'il a reçu ces informations, il les stocke à la fin d'une liste chainée.
        \item Le thread principal quant à lui exécute les calculs de collision et met à jour les informations des objets animés en fonction des actions effectuées par les joueurs. Pour faire cela, le thread reçoit une liste d'actions remplie par le deuxième thread du serveur et utilise les informations qu'elle contient pour savoir quels objets doivent être modifiés et de quelle manière. Il se charge ensuite, après avoir calculé toutes les implications d'une action reçue, de diffuser les informations aux clients.
    \end{itemize}

    %\subsubsection*{Modélisation}

    \subsection{Communications et synchronisation}
	\label{comm}
    Pour que chaque partie du projet obtienne les informations dont elle a besoin pour faire ses calculs, il fallait qu'elles puissent communiquer entre elles. Dans un jeu en réseau, la vitesse de transmission des informations est extrêmement importante. Mais la vitesse de transmission n'est pas basée uniquement sur la bande passante. En effet, le poids des données transmises a une grande importance dans le temps de transfert des informations. Il nous a fallu réfléchir à la méthode de communication et au mode de transmission entre les clients et le serveur. Nous nous sommes aussi penché sur les informations que nous communiquons sur le réseau afin d'alléger les transmissions. Nous avons rencontré lors du développement un problème de surcharge que nous présentons ici.


        \subsubsection*{Qui communique quoi, à qui et comment?}
    La méthode de communication à laquelle nous avons tout de suite pensé est l'utilisation de sockets. En effet, c'est la technologie que nous maitrisions le mieux. Pour échanger les informations, nous avons pris la décision d'utiliser la méthode connectée \texttt{Transmission Control Protocol}, protocole de contrôle de transmissions en français, plus souvent appelée simplement \texttt{TCP}. En effet, cette méthode assure la bonne réception des données ce qui permet d'être sûr que les informations sont transmises dans leur intégrité. La seconde possibilité était la méthode non connectée \texttt{User Datagram Protocol} (\texttt{UDP}, en français protocole de datagramme utilisateur) mais l'absence de certitude de la bonne réception des données nous est apparue rédhibitoire pour le projet que nous développons.

     \texttt{SFML} propose un module de communication appelé module \texttt{Network}. Ce module met à disposition un objet \texttt{socketTCP} qui propose toutes les méthodes nécessaires au fonctionnement d'une communication basée sur des sokets en mode connecté.

     Dans le projet, il existe une connexion entre un client et le serveur comme présenté dans la figure \ref{archiComm}. Les sockets proposées par SFML étant bidirectionnelles, nous n'avions pas besoin de plus.

     Chaque client envoie au serveur les informations des actions des joueurs en fonction des touches appuyées. Le serveur reçoit ces informations, les traite puis communique les résultats aux clients.


    %Qu'est ce que l'on a centralise sur le serveur et garde sur le client
    \begin{figure}[htb]
        \centering
        \includegraphics[scale=0.25]{img/Architecture.jpg}
        \caption{Architecture des communications entre le serveur et les clients}
        \label{archiComm}
    \end{figure}

    \subsubsection*{Des communications légères}
    Comme expliqué précédemment, pour garantir un jeu fluide et en temps réel, il fallait que les données transitant sur le réseau soient les plus légères possible. Le partage des calculs expliqué dans la partie \ref{archiJeuReseau} est responsable d'une bonne partie de l'allègement des données. En effet, les données d'affichage (textures, couleur des objets, positionnement des sprites, etc...) étant calculées sur le client, elles n'ont pas besoin d'être transmises.
    Il y a deux types d'objets différents qui sont transmis du serveur au client : les objets animés mobiles (personnages et monstres) et les objets animés fixes (gemmes, portes).

     \begin{itemize}
        \item Les objets mobiles ont besoin de plus d'informations que les fixes. Pour les objets de type joueur, il est nécessaire pour l'affichage d'avoir comme informations leur position (coordonnées $x$ et $y$), leur action, leur direction, leur score et leur état. Ce sont donc six valeurs qui sont transmises.
        \item Les objets fixes eux n'ont besoin de transmettre que leur position (coordonnées $x$ et $y$) et leur état.
    \end{itemize}


    \subsubsection*{Optimisation}
    Pour alléger encore les communications après avoir décidé d'envoyer le minimum d'informations, nous avons mis en place différents mécanismes pour non plus diminuer le poids des données mais pour diminuer le nombre de transmissions.

        \begin{itemize}
        \item Le premier mécanisme mis en place se trouve du côté du client. Les informations des entrées clavier ne sont transmises que s'il y a un changement d'état d'une touche. Si un joueur appuie sur une touche, l'information de l'appui sera envoyée au serveur. S'il reste appuyé sur cette touche, le client ne transmettra pas l'information et le serveur considèrera toujours la touche comme appuyée.  %TODO commentaire LP : "latence ?" Je vois pas ce qu'il a voulu dire..... :( Moi non plus !
        Si le joueur relâche la touche, le client envoie cette information de changement d'état au serveur qui pourra considérer la touche comme relâchée. Ceci fonctionne très bien et allège les communications surtout lorsque des touches sont appuyées continuellement.
       

    \item Un autre mécanisme mis en place se trouve quant à lui sur le serveur. Les informations transmises du serveur au client concernant les objets animés fixes sont leur position et leur état. La position de ces objets ne pouvant changer, elle n'est transmise qu'une seule fois lors du premier échange entre le serveur et le client pour que ce dernier initialise ces objets avec les bonnes valeurs. Dans les communications suivantes, la seule information transmise est l'état des objets permettant de savoir si ils sont affichés ou non. Pour ne pas surcharger la socket, nous avons décidé de mettre en place un algorithme qui ne transmet l'état des objets animés fixes que si ce dernier a eu une modification. Ainsi, si l'objet ne change pas d'état, aucune transmission n'est requise pour lui.
    Un troisième mécanisme d'optimisation est expliqué dans la section suivante. Nous avons dû y réfléchir suite à un gros problème de surcharge sur la socket.

        \end{itemize}

    \subsubsection*{Un problème de surcharge}
    %Pour appuyer l'importance de l'optimisation, nous allons vous décrire un problème sérieux que nous avons rencontré lors du développement de notre projet.
    Alors que nous testions les premières communication entre un client seul et un serveur, de gros problèmes de latence sont apparus. Au démarrage du client, l'affichage était fluide quoique un peu décalé par rapport aux entrées du clavier. Mais après quelques minutes de jeu, le tout devenait saccadé et injouable.
    Le soucis provenait d'une surcharge de la socket. En effet, nous transmettions les informations du serveur vers le client à chaque itération de la boucle de calcul des collisions et des déplacements. Les calculs étaient trop rapide et le nombre de transmissions devenait vite trop important pour la socket. Cette dernière stockait les communications dans sa file d'attente ce qui créait cette latence et ce décalage entre les entrées clavier et le rendu à l'écran.

    Pour résoudre ce problème, nous avons placé un \textit{timer} dans la boucle de calcul responsable de la latence. Le nombre d'envois a été réglé aux alentours de 60 images par seconde. Ainsi, nous avons énormément diminué le nombre d'envois, ce qui a considérablement allégé la charge sur la socket. %TODO Commentaire LP : penser à paramètrer : parametrer quoi? nkqdmoi gmohmihobm gb
    Nous nous rendons bien compte, avec ce problème, de l'importance de l'optimisation dans le développement d'un projet en réseau. 

    \subsection{Un objet englobant les objets}
    Dans un niveau, il existe plusieurs objet différents. Pour la mise à jour des objets ou leur transmission sur le réseau, il aurait été peu optimal en terme de code de les gérer individuellement. Pour éviter cette gestion au cas par cas, nous avons mis en place un objet \texttt{WorldObjects} qui joue le rôle de conteneur pour les objets du monde.
    À la construction du monde, cet objet conteneur est initialisé avec les autres objets du monde. Ensuite, à chaque itération de la boucle de jeu dans le thread de calcul, c'est ce conteneur qui gère les appels aux méthodes des objets du monde.
    Ce système permet de gérer automatiquement tous les objets du niveau quelque soit leur type et leur nombre.


    \subsection{Production}
    \subsection*{Extraits de code}
    \label{code}
    
	L'algorithme \ref{CodeTmx} présente la lecture du fichier \texttt{tmx} à la création du serveur pour l'implémentation des objets \texttt{Box2D} faisant partie du niveau. Notons qu'il est possible d'attribuer un type à un objet dans \texttt{Tiled}. Nous nous servons de cette possibilité pour définir la porte de sortie du niveau qui est un objet interactif, contrairement aux plateformes.
    
    \lstset{caption={Création des objets Box2D à la lecture du fichier \texttt{tmx}},label=CodeTmx}
\begin{lstlisting}
/* Initialisation de la carte tmx */
Tmx::Map *map = new Tmx::Map();
map->ParseFile("../Img/maps/level01.tmx");

Door* exitDoor;

// Parcours de tous les groupes d'objets contenus dans le fichier
for (int i = 0; i < map->GetNumObjectGroups(); ++i) {
	
	const Tmx::ObjectGroup *objectGroup = map->GetObjectGroup(i);
		
	// Parcours de tous les objets du groupe
	string type;
	for (int j = 0; j < objectGroup->GetNumObjects(); ++j) {
		// Get an object.
		const Tmx::Object *object = objectGroup->GetObject(j);

		type = object->GetType();
	
		if (type == "door") { 
			exitDoor = new Door(&world, object);
		} else {
			b2BodyDef groundBodyDef; 
			b2Vec2 groundPosition = sfmlToBox2dPosition(sf::Vector2f(static_cast<float>(object->GetX()) + (static_cast<float>(object->GetWidth())/2), 
			static_cast<float>(object->GetY()) + (static_cast<float>(object->GetHeight())/2)));
			groundBodyDef.position.Set(groundPosition.x, groundPosition.y);
	
			b2Body* groundBody = world.CreateBody(&groundBodyDef);
	
			b2PolygonShape groundBox;
			float groundWidth = sfmlToBox2dLength(static_cast<float>(object->GetWidth())/2);
			float groundHeight = sfmlToBox2dLength(static_cast<float>(object->GetHeight())/2);
			groundBox.SetAsBox(groundWidth, groundHeight); 
	
			b2FixtureDef fixture;
			fixture.shape = &groundBox;
			fixture.density = 1.0f;
	
			groundBody->CreateFixture(&fixture);
		}			
	}
}

delete map;
\end{lstlisting}

	\medskip
	L'algorithme \ref{CodeConversion} présente les fonctions de conversion d'une position entre \texttt{Box2D} et \texttt{SFML}.

\lstset{caption={Fonctions de conversion Box2D / SFML},label=CodeConversion}
\begin{lstlisting}
#define SCALE 0.03f

b2Vec2 sfmlToBox2dPosition(sf::Vector2f sf_position) {
	b2Vec2 b2d_position;

	b2d_position.x = sf_position.x * SCALE;
	b2d_position.y = (WINDOW_HEIGHT - sf_position.y) * SCALE;

	return b2d_position;
}


sf::Vector2f box2dToSfmlPosition(b2Vec2 b2d_position) {
	return sf::Vector2f(b2d_position.x / SCALE, WINDOW_HEIGHT - (b2d_position.y / SCALE));
}
\end{lstlisting}

	\medskip
	L'algorithme \ref{CodeAnimation} déroule les différents tests que nous devons faire pour afficher un personnage joueur chez le client. Il est ainsi nécessaire de savoir dans quelle direction le joueur regarde ainsi que l'action qu'il est en train d'effectuer (saut, course, saut en déplacement, sur place) pour déterminer quelle texture utiliser. Ensuite, nous plaçons le sprite sur la texture au bon endroit selon la séquence à laquelle nous nous trouvons. Cette séquence étant incrémenté à chaque tour de la boucle de jeu.

\lstset{caption={Fonction de dessin d'un joueur},label=CodeAnimation}
\begin{lstlisting}
void CharacterClient::draw(sf::RenderWindow& w) {
	if (chAction == DEAD) {
		characterSprite.setTexture(characterDead, true);
				characterSprite.setTextureRect(sf::IntRect(textureDeadSequence[sequence].x,
				textureDeadSequence[sequence].y, 30, 27));
	} else {

		if (chDirection == RIGHT) {
		/* Le personnage cour vers la droite */
			if (chAction == RUNNING) {
				characterSprite.setTexture(characterRunRight, true);
				characterSprite.setTextureRect(sf::IntRect(textureRunRightSequence[sequence].x,
				textureRunRightSequence[sequence].y,27, 30));
			}
			/* Le personnage regarde a droite a l'arret */
			if(chAction == FACING) {
				characterSprite.setTexture(characterFacingRight);
				characterSprite.setTextureRect(sf::IntRect(textureFaceRightSequence[sequence].x,
					textureFaceRightSequence[sequence].y,27, 30));
			}
			/* Le personnage regarde a droite en saut */
			if (chAction == JUMPING || chAction == JUMPRUNNING) {
				characterSprite.setTexture(characterJumpingRight);
				characterSprite.setTextureRect(sf::IntRect(textureJumpRight.x,
					textureJumpRight.y,27, 30));
			}


		} else if (chDirection == LEFT) {
			/* Le personnage cour vers la gauche */
			if (chAction == RUNNING) {
				characterSprite.setTexture(characterRunLeft);
				characterSprite.setTextureRect(sf::IntRect(textureRunLeftSequence[sequence].x,
					textureRunLeftSequence[sequence].y,27, 30));
			}
			/* Le personnage regarde a gauche a l'arret */
			if (chAction == FACING) {
				characterSprite.setTexture(characterFacingLeft);
				characterSprite.setTextureRect(sf::IntRect(textureFaceLeftSequence[sequence].x,
				textureFaceLeftSequence[sequence].y,27, 30));
			}
			/* Le personnage regarde a gauche en saut */
			if (chAction == JUMPING || chAction == JUMPRUNNING) {
				characterSprite.setTexture(characterJumpingLeft);
				characterSprite.setTextureRect(sf::IntRect(textureJumpLeft.x,
					textureJumpLeft.y,27, 30));
			}
		} 
	}

	/* Place le sprite a la position du personnage */
	characterSprite.setOrigin(CHARACTER_WIDTH/2, CHARACTER_HEIGHT.0/2); 
	characterSprite.setPosition(position.x, position.y);

	w.draw(characterSprite);
}
\end{lstlisting}

	\medskip
	La fonction décrite dans l'algorithme \ref{CodeWorldListener} gère le contact entre les objets qui implémentent l'interface \texttt{ContactObject}. La bibliothèque \texttt{Box2D} permet de détecter qu'il y a un contact entre deux corps créés mais ne permet pas de savoir exactement lesquels ni leur type. C'est pourquoi nous avons dû créer une interface commune à tous ces objets ainsi qu'un énumérateur de types pour appeler différentes fonctions selon les cas. 
	
	Quand deux objets sont en contact, il faut donc analyser quel est leur type. Dans notre cas, nous ne nous intéressons qu'aux contacts entre les joueurs et un monstre, une gemme ou une porte.

\lstset{caption={Écoute des contacts entre objets surveillés par le \texttt{WorldListener}}, label=CodeWorldListener}
\begin{lstlisting}
void MyWorldListener::BeginContact(b2Contact* contact) { 
	void* bodyUserDataA = contact->GetFixtureA()->GetBody()->GetUserData();
	void* bodyUserDataB = contact->GetFixtureB()->GetBody()->GetUserData();

	ContactObject* contactObjectA, *contactObjectB;
	if (bodyUserDataA) {
		contactObjectA = static_cast<ContactObject*>( bodyUserDataA );
		contactObjectA->startContact();
	}

	if (bodyUserDataB) {
		contactObjectB = static_cast<ContactObject*>( bodyUserDataB );
		contactObjectB->startContact();
	}

	if (bodyUserDataA && bodyUserDataB) {
		if (contactObjectA->getType() == PLAYER) {
			CharacterServer* player = static_cast<CharacterServer*>(contactObjectA);

			switch (contactObjectB->getType()) {
			case MONSTER :
				player->die();
				break;

			case DOOR :
				player->win();
				break;

			case GEM :
				player->collect(static_cast<GemServer*>(contactObjectB), serverWorldObjects);
				break;

			default :
				break;
			}
		} else if (contactObjectB->getType() == PLAYER) {
			CharacterServer* player = static_cast<CharacterServer*>(contactObjectB);

			switch (contactObjectA->getType()) {
			case MONSTER :
				player->die();
				break;

			case DOOR :
				player->win();
				break;

			case GEM :
				player->collect(static_cast<GemServer*>(contactObjectA), serverWorldObjects);
				break;

			default :
				break;
			}
		}		
	}
}
\end{lstlisting}

	\subsubsection*{Captures d'écran}
	La figure \ref{dead_guy} représente l'animation d'un personnage lorsqu'il meurt en entrant au contact d'un monstre. Ici, il reste encore un joueur dans la partie, le joueur rouge. Si le second joueur meurt lui aussi, un message s'affiche sur l'écran et la partie est terminée, comme illustré par la capture d'écran en figure \ref{looser}.
	
	Lorsque l'un des joueurs atteint la porte qui représente la fin du niveau, la sortie, un message s'affiche pour informer tous les joueurs de la victoire. Dans le cas où c'est le client actuel qui termine la partie, le message \textit{"You win !"} apparaît comme montré par la figure \ref{winner}. Si c'est un joueur ami qui trouve la sortie, la figure \ref{friend_winner} montre qu'un message différent apparaît.

	Les joueurs ont pour objectif de capturer des gemmes pouvant avoir différentes couleurs pour gagner des points avant de terminer un niveau. Le score de chacun des joueurs est affiché en haut à gauche de la fenêtre de jeu. La figure \ref{capture} montre le joueur bleu sur le point de capturer une gemme jaune, qui rapporte 10 points. Celui-ci a déjà capturé trois gemmes jaunes et possède donc un score de 30 points.
	
	
	\begin{figure}[h]
        \centering
        \includegraphics[scale=0.45]{img/dead_blue_guy.jpg}
        \caption{Joueur bleu tué par un monstre}
        \label{dead_guy}
    \end{figure}
    
    \begin{figure}[h]
        \centering
        \includegraphics[scale=0.45]{img/you_loose.jpg}
        \caption{Les deux joueurs sont morts}
        \label{looser}
    \end{figure}
    
    \begin{figure}[h]
        \centering
        \includegraphics[scale=0.45]{img/you_win.jpg}
        \caption{Le joueur rouge termine la partie, vu par lui-même}
        \label{winner}
    \end{figure}
    
    \begin{figure}[h]
        \centering
        \includegraphics[scale=0.45]{img/your_friend_win.jpg}
        \caption{Le joueur bleu termine la partie, vu par le joueur rouge}
        \label{friend_winner}
    \end{figure}
    
    \begin{figure}[h]
        \centering
        \includegraphics[scale=0.45]{img/capture_gemme.jpg}
        \caption{Le joueur bleu saute et capture une gemme jaune}
        \label{capture}
    \end{figure}
    
    


\clearpage
\section{Bilan}
	À la fin de ce projet, nous pouvons faire le point sur ce qui a été fait par rapport aux objectifs que nous nous étions fixés au départ et sur le déroulement du développement.
	
	
	\subsection{État de l'application}
 	L'objectif initial de notre projet a été rempli. Nous avons réalisé le développement d'un niveau de jeu vidéo en réseau en accentuant notre travail sur les aspects réseau et synchronisation. Nous avons également dû réfléchir à des solutions pour optimiser notre code le rendre plus performant, rendant notre application jouable sur tous les ordinateurs quelque soit leur puissance de calcul. 
		
	Nous avons mis en place des mécanismes de synchronisation sur la file d'action reçue par le serveur, nous assurant que peu importe le nombre de joueurs dans la partie, il n'y aura pas de conflit d'écriture ou de lecture dans celle-ci. L'application peut ainsi accueillir potentiellement un nombre illimité de joueurs même si elle est actuellement paramétré pour jouer à deux.
	
	La manière dont a été implémentée la totalité du jeu, aussi bien du côté client que du côté serveur, le rend très modulable et paramétrable. On peut très facilement ajouter d'autres objets dans notre monde, que ce soit un différent type d'ennemi ou des nouveaux objets avec lesquels les joueurs peuvent interagir. Actuellement, les joueurs peuvent récolter uniquement des gemmes, mais il est très simple d'ajouter un nouvel objet, des pièces par exemple, que les joueurs peuvent ramasser. Il suffit que l'objet ou le nouvel ennemi créé sur le serveur hérite de la classe \texttt{ContactObject} et ensuite l'écoute des interactions avec celui-ci se fera d'elle-même. 
	Nous pouvons également paramétrer le nombre de joueurs devant être attendus avant de commencer la partie. Et, grâce à la généricité des communications entre nos clients et le serveur, chaque joueur peut avoir sa propre configuration de touches pour jouer. Il serait également très facile de pouvoir changer la configuration afin jouer avec une manette plutôt qu'avec le clavier.
	
	\medskip
	Malgré l'aboutissement du projet, il reste une fonctionnalité que nous aurions souhaité implémenter mais qui est finalement manquante. En effet, nous aurions aimé créer une action pouvant être déclenchée uniquement par la collaboration de deux joueurs. Celle-ci n'a pas été faite car au fil du projet, nous nous sommes concentrés sur d'autres points que nous voulions corriger ou améliorer. Cette possibilité serait cependant aisément intégrable au projet actuel.
	
	\subsection{Chronologie du projet}
	Le travail durant le projet s'est déroulé en plusieurs étapes successives. Il a d'abord fallu définir clairement les objectifs et les technologies que nous souhaitions utiliser. Ensuite, nous avons pris en main ces différentes technologies. Et finalement, nous avons développé le jeu en lui-même par petites étapes, en apportant les corrections et modifications nécessaires aux différentes avancées.
	
	\medskip
	Voici plus en détails comment s'est déroulé le projet :
	\begin{enumerate}
		\item Définition exacte des objectifs du projet ainsi que des priorités.
		\item Réflexion sur l'architecture à adopter. Étude des technologies utilisables. Choix de la bibliothèque \texttt{SFML} et prise en main de cette dernière.
		\item Décision d'utiliser un moteur physique pour plus de réalisme dans le jeu. Mise en place de \texttt{Box2D}.\\
		Premiers essais avec l'affichage d'un rectangle simple en guise de plateforme et un seul joueur avec les animations de déplacement.
		\item Observation de la latence importante contraignant le jeu. Mise en place du \textit{timer} pour corriger ce problème.
		\item Dessin de la première carte avec le logiciel \texttt{Tiled}. Adaptation et mise en place de la bibliothèque pour parser les fichiers \texttt{tmx}. Création des objets dans le jeu selon les informations lues dans le fichier.
		\item Correction d'une erreur dans le saut. Les joueurs pouvaient sauter en étant déjà en l'air.
		\item Mise en place du \texttt{WorldListener}. Création des monstres et des gemmes ainsi que des implications des interaction entre les différents objets et le joueur. \\
		Ajout de l'animation en cas de mort d'un joueur au contact d'un monstre.
		\item Gestion et affichage du score des joueurs. 
		\item Mise en place du système \texttt{WorldObjects} pour généraliser et alléger les échanges entre le serveur et les clients. \\
		Mise en place du \texttt{mutex} sur la liste d'actions pour palier tout problème de synchronisation.
		\item Ajout de l'affichage des messages en cas de fin de partie par mort des deux joueurs ou victoire de l'un des deux.
	\end{enumerate}
	
	
	\subsection{Bilan pédagogique et personnel}
	Tout au long de ce projet, nous avons appris énormément sur tous les aspects du développement de logiciels vidéo-ludiques. Nous avons découvert comment étaient réellement articulés tous les modules qui composent un jeu vidéo. Des moteurs graphique et physique au système d'animation, en passant par des questions d'optimisation et de communications en réseau, nous avons enrichi nos connaissances non seulement dans la création de jeux mais aussi par rapport à tout ce que nous avons appris dans notre spécialité Systèmes Distribués et Réseaux.
Faire le lien entre nos cours et une de nos passions a donné un coté extrêmement concret à nos heures d'apprentissage théorique et a été une réelle motivation.

	Travailler ensemble n'a pas été une difficulté puisque ce n'est pas le premier projet que nous faisions tous les deux. Cela a permis de confirmer que nous pouvions collaborer sans problème. Nous avons chacun pu améliorer nos compétences dans la programmation en \texttt{C++} et sur l'utilisation de \texttt{Visual Studio}, ce qui sera un avantage important pour notre stage à venir.


\clearpage
\section*{Conclusion}
\addcontentsline{toc}{section}{Conclusion}
	Ce projet nous a permis d'enrichir nos connaissances sur les problématiques du développement de jeux vidéo en réseau. Nous avons pu constater l'importance de l'optimisation des échanges lorsque l'on est en présence d'une application qui communique très fréquemment en réseau. De même, nous avons vite remarqué que faire une boucle infinie de jeu pouvait entraîner des surcharges si on ne mettait pas en place des règles de temporisation. Le fait de proposer nous même le sujet nous a confronté à une problématique supplémentaire qui est de définir les objectifs et priorités de développement. C'est une bonne expérience car nous n'avons pas souvent eu l'occasion de le faire durant notre cursus universitaire.

	L'application des connaissances acquises au cours de nos années d'études dans un projet concret que nous avons proposé et développé dans son intégralité a été très gratifiant. De plus, ce projet touche de près à une de nos passions communes, ce qui a été un plus tant au niveau de l'apport de connaissances que de la motivation de faire ce qui nous plaît. 


\clearpage

\renewcommand\refname{Webographie}
%Références (webographie) (lien + dates)
%TODO dates ? date? d'anniversaire? 
\nocite{*}
\bibliographystyle{plain}
\bibliography{biblio}

\clearpage
\listoffigures
%\listoftables
\lstlistoflistings

% Résumé français + anglais
% Mots clefs
\clearpage
\thispagestyle{empty}
%Communications réseau, moteur de graphisme et moteur physique dans un jeu de plateforme multi-joueurs
\section*{Résumé}
	Lors de notre dernière année de Master Informatique en spécialité Systèmes Distribués et Réseaux, nous avons eu l'occasion de développer un projet semestriel sur une durée de 4 mois. Nous avons élaboré nous-même le sujet de celui-ci. Il s'agit du développement d'un jeu vidéo de plateformes en réseau. Le jeu est multi-joueurs et très simple d'utilisation.

	\medskip
	Pour mener à bien notre projet, nous avons utilisé la bibliothèque \texttt{SFML} pour le moteur graphique pour l'affichage de notre jeu. Nous avons également utilisé que bibliothèque \texttt{Box2D} pour le moteur physique. Le jeu a été implémenté selon une architecture client-serveur. Le client ne s'occupe que de l'affichage des données et le serveur effectue tous les calculs de position, contact entre les objets et les implications que ceux-ci ont.
	
	La priorité a été mise sur les communications réseau et la synchronisation des données entre les clients et le serveur. 

\paragraph*{Mots clefs} C++, SFML, Box2D, Tiled, TmxParser, jeu vidéo, réseau, communications, synchronisation

\section*{Summary}
	During our last year of IT Master's degree in speciality Distributed Systems and Network , we had the opportunity to develop an annual project over a period of 4  months. We choosed ourselves the subject. We developed a platform video game in network. This game is multiplayer and aims to be very simple to understand.

	\medskip
	To do our project, we used the graphic engine library \texttt{SFML} for the display of our game. We also used the library \texttt{Box2D} which is a physics engine. The game was implemented according to the client-server model. The client is only focused on the display of the data and the server performs all the computations of positions, analyzes contacts between objects and implications they have.
	
Priority was put on the network communications and data synchronization between client and server.


\paragraph*{Keywords} C++, SFML, Box2D, Tiled, TmxParser, video game, network, communications, synchronization

\end{document}